Slient Blog

RxJava RxPermissions基础

2017-03-16

开源项目

RxPermissions地址:https://github.com/tbruyelle/RxPermissions

build.gradle

1
2
3
4
5
6
7
repositories {
jcenter() // If not already there
}
dependencies {
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.3@aar'
}

不了解6.0权限问题可以参考

咕咚大神的博客
先看官方的Sample(看完下面的再看这个会更清晰哦~)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
RxView.clicks(mBtnPermission)
// Ask for permissions when button is clicked
.compose(rxPermissions.ensureEach(Manifest.permission.CAMERA))
.subscribe(new Action1<Permission>() {
@Override
public void call(Permission permission) {
Log.i(TAG, "Permission result " + permission);
if (permission.granted) {
releaseCamera();
camera = Camera.open(0);
try {
camera.setPreviewDisplay(mSurfaceView.getHolder());
camera.startPreview();
} catch (IOException e) {
Log.e(TAG, "Error while trying to display the camera preview", e);
}
} else if (permission.shouldShowRequestPermissionRationale) {
// Denied permission without ask never again
Toast.makeText(getApplicationContext(),
"Denied permission without ask never again",
Toast.LENGTH_SHORT).show();
} else {
// Denied permission with ask never again
// Need to go to the settings
Toast.makeText(getApplicationContext(),
"Permission denied, can't enable the camera",
Toast.LENGTH_SHORT).show();
}
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable t) {
Log.e(TAG, "onError", t);
}
},
new Action0() {
@Override
public void call() {
Log.i(TAG, "OnComplete");
}
});

用法

如果你使用的是0.9版本之前,可以直接获取单例

1
RxPermissions.getInstance(this

之后的版本,创建RxPermission实例

1
RxPermissions rxPermission = new RxPermissions(this);

一共有四种方式获取权限( 我们来获取 CAMERA permission和 VIBRATE permission)

  • Observable.compose(rxPermissions.ensure())

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    RxView.clicks(mBtnPermission)
    .compose(rxPermissions.ensure(Manifest.permission.CAMERA,Manifest.permission.VIBRATE))
    .subscribe(new Action1<Boolean>() {
    @Override
    public void call(Boolean aBoolean) {
    if (aBoolean) {
    Log.i("RxPermissions:","all permissions get success");
    }else {
    Log.i("RxPermissions:","must has one ore more permissions get failed");
    }
    }
    });
  • Observable.compose(rxPermissions.ensureEach())

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    RxView.clicks(mBtnPermission)
    .compose(rxPermissions.ensureEach(Manifest.permission.CAMERA,Manifest.permission.VIBRATE))
    .subscribe(new Action1<Permission>() {
    @Override
    public void call(Permission permission) {
    if (permission.granted){
    Log.i("RxPermissions:",permission.name+"this permission get success");
    }else{
    Log.i("RxPermissions:",permission.name+"this permission get failed");
    }
    }
    });
  • new RxPermissions(this).request(permissions)

1
2
3
4
5
6
7
8
9
10
11
12
rxPermissions.request(Manifest.permission.CAMERA)
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
if (aBoolean) {
Log.i("RxPermissions:","all permissions get success");
}else {
Log.i("RxPermissions:","must has one ore more permissions get failed");
}
}
});
  • new RxPermissions(this).requestEach(permissions)
1
2
3
4
5
6
7
8
9
10
11
rxPermissions.requestEach(Manifest.permission.CAMERA)
.subscribe(new Action1<Permission>() {
@Override
public void call(Permission permission) {
if (permission.granted){
Log.i("RxPermissions:",permission.name+"this permission get success");
}else{
Log.i("RxPermissions:",permission.name+"this permission get failed");
}
}
});

我们来看看request和ensure的源码你就会明白所以然了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* Request permissions immediately, <b>must be invoked during initialization phase
* of your application</b>.
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public Observable<Boolean> request(final String... permissions) {
return Observable.just(null).compose(ensure(permissions));
}
/**
* Map emitted items from the source observable into {@code true} if permissions in parameters
* are granted, or {@code false} if not.
* <p>
* If one or several permissions have never been requested, invoke the related framework method
* to ask the user if he allows the permissions.
*/
@SuppressWarnings("WeakerAccess")
public Observable.Transformer<Object, Boolean> ensure(final String... permissions) {
return new Observable.Transformer<Object, Boolean>() {
@Override
public Observable<Boolean> call(Observable<Object> o) {
return request(o, permissions)
// Transform Observable<Permission> to Observable<Boolean>
.buffer(permissions.length)
.flatMap(new Func1<List<Permission>, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(List<Permission> permissions) {
if (permissions.isEmpty()) {
// Occurs during orientation change, when the subject receives onComplete.
// In that case we don't want to propagate that empty list to the
// subscriber, only the onComplete.
return Observable.empty();
}
// Return true if all permissions are granted.
for (Permission p : permissions) {
if (!p.granted) {
return Observable.just(false);
}
}
return Observable.just(true);
}
});
}
};
}

request请求一般放在程序初始化的时候比如onCreat()中,而且它的内部也是一个ensure(permissions),经过compose(ensure())最终返回值是一个存放boolean值的Observable如果返回true表示请求中的所有权限的已经成功获取,如果返回false表示至少有一个权限没有获取成功。所以不好分别处理,如果选择分别处理的话我们还是用requestEach去分别处理这个源码大家自己去看一看很简单的,内部使用的是ensureEach(permissions),返回的是被处理过的permission,通过它的状态我们可以判断是否获取权限,以上的方法在6.0之前的手机中,会默认认为你已经处理过权限也就是响应地方返回true。

总结(建议)

  • 在初始程序的时候请求一个权限: new RxPermissions(this).request(permissions) or new RxPermissions(this).requestEach(permissions)
  • 在初始程序的时候请求多个权限: new RxPermissions(this).requestEach(permissions)
  • 在指定的位置,时机请求一个权限:Observable.compose(rxPermissions.ensure()) or Observable.compose(rxPermissions.ensureEach())
  • 在指定的位置,时机请求多个权限:Observable.compose(rxPermissions.ensureEach())

很简单的教程,目的是让大家直到有这种方式去解决权限问题,更多的还是要靠大家多看多写。see you~

重要的事情说一遍“多看源码”

Tags: Android
使用微信添加

若你觉得我的文章对你有帮助,请添加我为好友

扫描二维码,分享此文章